import { useMemoizedFn } from 'ahooks'
import { useEffect, useState } from 'react'
import { Text, View } from '@tarojs/components'
import { Cascader, Loading, Popup, SafeArea } from '@taroify/core'
import type { FC, ReactNode } from 'react'
import type { CascaderDataOption, CascaderEventOption } from '@taroify/core/cascader'

import { listAreas } from '@/apis/base'
import { useLoadingify } from '@/hooks/useLoadingify'

export interface AreaSelectProps {
  className?: string
  open?: boolean
  title?: ReactNode
  animated?: boolean
  ellipsis?: boolean
  labelKey?: string
  valueKey?: string
  swipeable?: boolean
  placeholder?: ReactNode
  onClose?: () => void
  onConfirm?: (value: string[], options: { label: string; value: string; index: number }[]) => void
}

export const AreaSelect: FC<AreaSelectProps> = ({
  className,
  open,
  animated,
  placeholder,
  swipeable,
  ellipsis = false,
  title = '请选择地区',
  labelKey = 'name',
  valueKey = 'id',
  onClose,
  onConfirm,
}) => {
  const [options, setOptions] = useState<CascaderDataOption[]>([])
  const [loading, fetchAreas] = useLoadingify(listAreas, { showLoading: false })

  const fetchOptions = useMemoizedFn(async () => {
    const res = await fetchAreas('0')
    setOptions(res)
  })

  useEffect(() => {
    if (open && !options.length) {
      fetchOptions()
    }
  }, [open, options])

  const loadData = useMemoizedFn(async (values: string[]) => {
    return await fetchAreas(values[values.length - 1])
  })

  const handleConfirm = (value: string[], options: CascaderEventOption[]) => {
    onConfirm?.(
      value,
      options.map((item) => ({ label: String(item.children), value: item.value, index: item.tabIndex }))
    )
    onClose?.()
  }

  return (
    <Popup open={open} placement="bottom" onClose={onClose}>
      <Popup.Close />
      <SafeArea className="relative" position="bottom">
        <Cascader
          className={className}
          title={title}
          options={options}
          animated={animated}
          ellipsis={ellipsis}
          swipeable={swipeable}
          placeholder={placeholder}
          fieldNames={{ label: labelKey, value: valueKey, children: 'children' }}
          loadData={loadData}
          onChange={handleConfirm}
        />
        {loading && (
          <View className="absolute top-0 left-0 size-full flex flex-center">
            <Loading direction="vertical">
              <Text>加载中...</Text>
            </Loading>
          </View>
        )}
      </SafeArea>
    </Popup>
  )
}

export default AreaSelect
